﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2010-06-11
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


//----------------------------------------------------------------
//
//----------------------------------------------------------------
struct IFTextureLock
{
    int   Pitch;                    // 跨度
    BYTE* pBits;                    // 首地址
};


struct IFTextureInfo
{
    UINT Width;                     // 贴图宽度（自动扩展到2的幂）
    UINT Height;                    // 贴图高度
    UINT MipLevels;                 // mipmap级别
    EF_FORMAT Format;               // 格式
    UINT srcWidth;                  // 文件的原始宽度（非2的幂，文件贴图时有效）
    UINT srcHeight;                 // 文件的原始高度
};


class IFTextureFile : public IFFileObject
{
public:
    UINT  nWidth;                   // 贴图宽度
    UINT  nHeight;                  // 贴图高度
    float fWGene;                   // fWGene=1/nWidth
    float fHGene;                   // fWGene=1/nHeight
    UINT srcWidth;                  // 文件的原始宽度
    UINT srcHeight;                 // 文件的原始高度

    // 取贴图ID
    virtual FIDTEXTURE GetTextureID() = 0;
    // 是否是立方贴图
    virtual bool IsCubeTexture(){ return HasProperty(eFP_CubeTexture); }
    // 是否还在多线程创建队列
    virtual bool IsInMultThread(){ return HasProperty(eFP_ThreadCreate); }
};


//----------------------------------------------------------------
// 贴图对象
//----------------------------------------------------------------
#include "Engine/IFRes_Texture_Object.h"


//----------------------------------------------------------------
//
//----------------------------------------------------------------
class IFTexture : public IFService
{
protected:
    explicit IFTexture()
        :IFService(0)
    {}

public:
    // 注册用户贴图（条件：eCD_DefTextureID < ID < eCD_AutoTexBegin）
    // .filename 贴图文件路径（游戏执行程序的相对目录，或者绝对目录）
    // .id 该贴图期望的ID号（如果ID=eCD_ErrorTex则自动生成ID，否则返回期望的ID）
    // .return 该贴图实际ID，失败返回eCD_ErrorTex
    virtual FIDTEXTURE Register(const WCHAR* filename, FIDTEXTURE id = eCD_ErrorTex) = 0;
    virtual FIDTEXTURE Register(const ACHAR* filename, FIDTEXTURE id = eCD_ErrorTex) = 0;
    // 通过已经注册的用户贴图ID创建贴图
    // .id 已经成功注册过的ID号
    // .multithread 是否使用多线程加载（建议使用）
    // .cube 是否是立方贴图
    // .return 返回值和参数id一样的值，但失败则返回eCD_ErrorTex
    virtual FIDTEXTURE Create(FIDTEXTURE id, bool multithread = true, bool cube = false) = 0;
    // 通过文件路径创建贴图
    // .filename: 文件路径
    // .multithread 是否使用多线程加载（建议使用）
    // .cube 是否是立方贴图
    // .return 贴图ID，失败返回eCD_ErrorTex
    virtual FIDTEXTURE Create(const WCHAR* filename, bool multithread = true, bool cube = false) = 0;
    virtual FIDTEXTURE Create(const ACHAR* filename, bool multithread = true, bool cube = false) = 0;
    // 通过文件缓存创建贴图，或者说是文件流，并非ARGB缓存
    virtual FIDTEXTURE Create(const BYTE* buf, size_t size) = 0;
    // 通过ARGB缓存创建贴图（宽高尺寸必须是2的幂）
    // buf的实际内存大小应为：buf[width*height*4]
    virtual FIDTEXTURE CreateByARGB(size_t width, size_t height, const BYTE* buf) = 0;
    // 创建指定格式贴图（立即创建，不进多线程队列）
    // .width,height: 贴图宽与高度
    // .mip_level: mipmap级别
    // .tt: 标记
    // .format: 格式
    // .pool: 放置池
    // .return 贴图ID，失败返回eCD_ErrorTex
    virtual FIDTEXTURE Create(UINT width, UINT height, UINT mip_level = 1, EF_TEXTURE_TYPE tt = eTT_Default, EF_FORMAT format = eFMT_A8R8G8B8, EF_POOL pool = ePL_Managed) = 0;
    // 创建地形高度+法线图
    virtual FIDTEXTURE CreateHM(FV_BYTE* in_argb8, FV_BYTE* out_argb8, bool init_it, float* hbuf) = 0;
    // 创建地形混合图
    virtual FIDTEXTURE CreateBlend(FV_BYTE* in_dxt5, FV_BYTE* out_dxt5, bool init_it, bool fwd_tools) = 0;
    // 创建 Perlin 噪音贴图（eFMT_A8L8格式）
    // .frequency [0-1]
    virtual FIDTEXTURE CreatePerlinNoise(UINT width, UINT height, float frequency = 0.1f, FV_BYTE* out_al8 = 0) = 0;
    // 消毁资源
    // .id: 被消毁的资源ID
    virtual void Destroy(FIDTEXTURE id) = 0;
    // 消毁资源
    // .id: 被消毁的资源ID，消毁以后并自动将id设为eCD_ErrorTex
    virtual void DestroyEx(FIDTEXTURE& id) = 0;
    // 锁定贴图信息，便于自定义填充图片
    // .id: 需要锁定的贴图ID
    // .lock: 返回锁定信息
    // .mip_level 锁定mipmap的级别，默认0
    // .flags: 锁定标记，详见EF_TEXTURE_LOCK
    virtual bool LockRect(FIDTEXTURE id, IFTextureLock& lock, BYTE mip_level = 0, EF_TEXTURE_LOCK flags = eTL_Normal) = 0;
    // 解锁贴图
    // .id: 需要解锁的贴图ID
    // .mip_level 与锁定时填的mip_level相同
    virtual void UnlockRect(FIDTEXTURE id, BYTE mip_level = 0) = 0;
    // 获得指定象素颜色
    // .id: 需要锁定的贴图ID
    // .x,y: 图片x,y坐标
    // .return 颜色值，坐标出界或颜色值本身就是0则返回0
    virtual DWORD GetPixel(FIDTEXTURE id, UINT x, UINT y) = 0;
    // 获取图片数据到缓冲区（只支持ARGB、XRGB格式贴图输出，其它格式请使用LockRect自行处理）
    // .id 贴图ID
    // .argb 输出到的argb缓冲区，长度为贴图的 width*height
    // .return 成功返回该图片信息，失败返回0
    virtual const IFTextureFile* const GetBuffer(FIDTEXTURE id, FV_BYTE& argb) = 0;
    // 保存到文件
    // .id 贴图ID
    // .filename 目标文件
    // .format 格式
    virtual bool SaveToFile(FIDTEXTURE id, const WCHAR* filename, EF_IMAGE_FORMAT format = eIF_PNG) = 0;
    virtual bool SaveToFile(FIDTEXTURE id, const ACHAR* filename, EF_IMAGE_FORMAT format = eIF_PNG) = 0;
    // 取得指定贴图信息（如果是仅注册过的，则只能得到路径信息，尺寸信息没有）
    // .id 查询的贴图ID
    virtual const IFTextureFile* const GetTexData(FIDTEXTURE id) const = 0;
    // 通过DC填充数据到贴图
    // .id 目标贴图ID
    // .dx,dy,dw,dh 目标贴图的坐标位置
    // .hdc 源DC
    // .sx,sy 源DC中的坐标
#if FUEL_OS_WINDOWS
    virtual bool FillByHDC(FIDTEXTURE id, int dx, int dy, int dw, int dh, HDC hdc, int sx, int sy) = 0;
#endif
    // 将一个贴图设为常用，即永注内存不消毁，直到程序结束
    virtual bool Solidify(FIDTEXTURE id) = 0;
    // 使用贴图（返回该数据地址，D3D的情况下返回的是贴图地址）
    virtual FTEXTURE_PTR UseTexture(FIDTEXTURE id) = 0;
};